#pragma once

#include <algorithm/crc.hpp>
#include <sheriffos.h>

namespace dji {
auto const kCrC8Table = CRCLib::CRC_8_MAXIM().MakeTable();
auto const kCRC16Table = CRCLib::CRC_16_MCRF4XX().MakeTable();

namespace ref_type {
// ------ 帧头 ------
struct [[gnu::packed, gnu::aligned(1)]] FrameHeader {
    uint8_t SOF; // 数据帧头，固定位 0xA5
    uint16_t DataLength; // 数据长度
    uint8_t SEQ; // 序列号
    uint8_t CRC8; // 数据帧头 CRC8 校验
};

// ------ 命令码 ID ------
enum CmdID : uint16_t {
    kGameStatus = 0x0001, // 0x0001 11  比赛状态数据 1Hz RxAll
    kGameResult = 0x0002, // 0x0002 1   比赛结果数据 结束 RxAll
    kRobotHp = 0x0003, // 0x0003 32  机器人血量 3Hz RxAll
    kFieldEvent = 0x0101, // 0x0101 4   场地事件 1Hz RxOwn
    kSupply = 0x0102, // 0x0102 4   场地补给站动作标识 补给弹丸 RxOwn
    kWarning = 0x0104, // 0x0104 3   警告数据 1Hz RxOwn
    kDart = 0x0105, // 0x0105 3   飞镖发射 1Hz RxOwn
    kRobotPerf = 0x0201, // 0x0201 13  机器人性能体系 10Hz RxMine
    kPowerAndHeat = 0x0202, // 0x0202 16  底盘功率和枪口热量 50Hz RxMine
    kRobotPos = 0x0203, // 0x0203 16  机器人位置 1Hz RxMine
    kRobotGain = 0x0204, // 0x0204 6   机器人增益 3Hz RxMine
    kAirSupport = 0x0205, // 0x0205 2   空中支援时间 1Hz RxDrone
    kDamageStatus = 0x0206, // 0x0206 1   伤害状态 1Hz RxMine
    kShootStatus = 0x0207, // 0x0207 7   射击数据 发射 RxMine
    kRemainProjectile = 0x0208, // 0x0208 6   剩余弹量 10Hz RxShooter
    kRFIDStatus = 0x0209, // 0x0209 4   RFID状态 3Hz RxWithRFID
    kDartCmd = 0x020A, // 0x020A 6   飞镖指令 3Hz RxDart
    kGroundPos = 0x020B, // 0x020B 40  地面机器人位置 1Hz RxSentry
    kRadarMark = 0x020C, // 0x020C 6   雷达标记进度 1Hz RxRadar
    kSentryDec = 0x020D, // 0x020D 4   哨兵决策信息 1Hz RxSentry
    kRadarDec = 0x020E, // 0x020E 1   雷达决策信息 1Hz RxRadar
    kInteraction = 0x0301, // 0x0301 127 交互数据 ≤30Hz Tx
    kCustomCtrl = 0x0302, // 0x0302 30  自定义控制器 ≤30Hz TxCtrl->RxMine
    kMapInteraction = 0x0303, // 0x0303 15  地图交互数据 TxPlayer->RxMine
    kKeyMouseCtrl = 0x0304, // 0x0304 12  键鼠遥控 30Hz TxPlayer->RxMine
    kRadarData = 0x0305, // 0x0305 10  地图接收雷达数据 ≤10Hz TxRadar->RxOwn
    kCustomCtrlNoUsed = 0x0306, // 0x0306 8   自定义操作控制器 ≤30Hz ----
    kSentryData = 0x0307, // 0x0307 103 地图哨兵数据 1Hz TxAuto->RxPlayer
    kMapData = 0x0308, // 0x0308 34  地图数据 3Hz TxMine->RxPlayer
};

// ------ 机器人 ID ------
enum class RobotID : uint16_t {
    kRedHero = 1,
    kRedEngineer = 2,
    kRedInfantry3 = 3,
    kRedInfantry4 = 4,
    kRedInfantry5 = 5,
    kRedDrone = 6,
    kRedSentry = 7,
    kRedDart = 8,
    kRedRadar = 9,
    kRedOutpost = 10,
    kRedBase = 11,
    kBlueHero = 101,
    kBlueEngineer = 102,
    kBlueInfantry3 = 103,
    kBlueInfantry4 = 104,
    kBlueInfantry5 = 105,
    kBlueDrone = 106,
    kBlueSentry = 107,
    kBlueDart = 108,
    kBlueRadar = 109,
    kBlueOutpost = 110,
    kBlueBase = 111,
};

// ----- 选手端 ID ------
enum class PlayerID : uint16_t {
    kRedHero = 0x0101,
    kRedEngineer = 0x0102,
    kRedInfantry3 = 0x0103,
    kRedInfantry4 = 0x0104,
    kRedInfantry5 = 0x0105,
    kRedDrone = 0x0106,
    kBlueHero = 0x0165,
    kBlueEngineer = 0x0166,
    kBlueInfantry3 = 0x0167,
    kBlueInfantry4 = 0x0168,
    kBlueInfantry5 = 0x0169,
    kBlueDrone = 0x016A,
    kRefereeServer = 0x8080,
};

template <CmdID IdT>
struct DataType {
    static_assert(IdT == kGameStatus or IdT == kGameResult or IdT == kRobotHp or
                  IdT == kFieldEvent or IdT == kSupply or IdT == kWarning or
                  IdT == kDart or IdT == kRobotPerf or IdT == kPowerAndHeat or
                  IdT == kRobotPos or IdT == kRobotGain or
                  IdT == kAirSupport or IdT == kDamageStatus or
                  IdT == kShootStatus or IdT == kRemainProjectile or
                  IdT == kRFIDStatus or IdT == kDartCmd or
                  IdT == kGroundPos or IdT == kRadarMark or
                  IdT == kSentryDec or IdT == kRadarDec or
                  IdT == kCustomCtrl or IdT == kMapInteraction or
                  IdT == kKeyMouseCtrl or IdT == kRadarData or
                  IdT == kCustomCtrlNoUsed or IdT == kSentryData or
                  IdT == kMapData,
                  "裁判系统数据类型不符合协议");
};

// ------ CRC16 整包校验 ------
using FrameTail = uint16_t;

template <typename DataType>
struct [[gnu::packed, gnu::aligned(1)]] FrameTemplate {
    FrameHeader Header;
    CmdID ID;
    DataType Data;
    FrameTail Tail;
};

template <>
struct [[gnu::packed, gnu::aligned(1)]] FrameTemplate<void> {
    FrameHeader Header;
    CmdID ID;
    FrameTail Tail;
};

// ---- 0x0001
using GameStatusDataType = DataType<kGameStatus>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kGameStatus> {
    enum : uint8_t {
        kRoboMasterDualMeet = 1,
        kRoboMasterIndividualEvent = 2,
        kIcraRoboMaster = 3,
        kRoboMaster3v3 = 4,
        kRoboMasterInfantry = 5,
    } GameType : 4;

    enum : uint8_t {
        kNotStart = 0,
        kPreparing = 1,
        kRefereeSelfCheck = 2,
        kCountDown = 3,
        kGameRunning = 4,
        kSettlement = 5,
    } GameProcess : 4;

    uint16_t StageRemainTimeSecond;
    uint64_t SyncTimeStamp;
};

// ---- 0x0002 */
using GameResultDataType = DataType<kGameResult>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kGameResult> {
    enum : uint8_t {
        kDraw = 0,
        kRedWin = 1,
        kBlueWin = 2,
    } Winner;
};

// ---- 0x0003 */
using RobotHpDataType = DataType<kRobotHp>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kRobotHp> {
    uint16_t Red1HP;
    uint16_t Red2HP;
    uint16_t Red3HP;
    uint16_t Red4HP;
    uint16_t Red5HP;
    uint16_t Red7HP;
    uint16_t RedOutpostHP;
    uint16_t RedBaseHP;
    uint16_t Blue1HP;
    uint16_t Blue2HP;
    uint16_t Blue3HP;
    uint16_t Blue4HP;
    uint16_t Blue5HP;
    uint16_t Blue7HP;
    uint16_t BlueOutpostHP;
    uint16_t BlueBaseHP;
};

// ---- 0x0101 */
using FieldEventDataType = DataType<kFieldEvent>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kFieldEvent> {
    uint32_t EventCode;
};

// ---- 0x0102 */
using SupplyDataType = DataType<kSupply>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kSupply> {
    uint16_t _ : 8;
    RobotID Who : 8;

    enum : uint8_t {
        kClose = 0,
        kPreparing = 1,
        kReleasing = 2,
    } ProjectileStep;

    uint8_t ProjectileNum;
};

// ---- 0x0104 */
using WarningDataType = DataType<kWarning>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kWarning> {
    enum : uint8_t {
        kBothSideYellowCard = 1,
        kYellowCard = 2,
        kRedCard = 3,
        kFail = 4,
    } level;

    uint8_t OffendingRobotID;

    uint8_t Count;
};

// ---- 0x0105 */
using DartDataType = DataType<kDart>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kDart> {
    uint8_t DartRemainTimeSecond;

    enum Target : uint16_t {
        kNone = 0,
        kOutposts = 1,
        kBaseFix = 2,
        kBaseMove = 3,
    };

    Target TargetHit : 2;
    uint16_t Count : 3;
    Target TargetSelected : 2;
    uint16_t _ : 9;
};

// ---- 0x0201 */
using RobotPerfDataType = DataType<kRobotPerf>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kRobotPerf> {
    uint8_t ID;
    uint8_t Level;
    uint16_t CurrentHP;
    uint16_t MaxHP;
    uint16_t CoolingRate;
    uint16_t HeatLimit;
    uint16_t PowerLimit;
    uint8_t IsGimbalOutput : 1;
    uint8_t IsChassisOutput : 1;
    uint8_t IsShooterOutput : 1;
    uint8_t _ : 5;
};

// ---- 0x0202 */
using PowerAndHeatDataType = DataType<kPowerAndHeat>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kPowerAndHeat> {
    uint16_t ChassisVoltage;
    uint16_t ChassisCurrent;
    float ChassisPower;
    uint16_t ChassisEnergyBuffer;
    uint16_t Shooter17mmHeat[2];
    uint16_t Shooter42mmHeatLimit;
};

// ---- 0x0203 */
using RobotPosDataType = DataType<kRobotPos>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kRobotPos> {
    float_t x;
    float_t y;
    float_t angle;
};

// ---- 0x0204 */
using RobotGainDataType = DataType<kRobotGain>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kRobotGain> {
    uint8_t Recovery;
    uint8_t Cooling;
    uint8_t Defence;
    uint8_t Vulnerability;
    uint16_t Attack;
};

// ---- 0x0205 */
using AirSupportDataType = DataType<kAirSupport>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kAirSupport> {
    enum : uint8_t {
        kCooling = 0,
        kReady = 1,
        kSupporting = 2,
    } Status;

    uint8_t TimeRemainSecond;
};

// ---- 0x0206 */
using DamageStatusDataType = DataType<kDamageStatus>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kDamageStatus> {
    uint8_t ArmorID : 4;

    enum : uint8_t {
        kUnderAttack = 0,
        kModuleOffline = 1,
        kSpeedOverLimit = 2,
        kHeatOverLimit = 3,
        kPowerOverLimit = 4,
        kTakeAHit = 5,
    } Reason : 4;
};

// ---- 0x0207 */
using ShootStatusDataType = DataType<kShootStatus>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kShootStatus> {
    enum : uint8_t {
        kProject17mm = 1,
        kProject42mm = 2,
    } Type;

    enum : uint8_t {
        kShooter17mm1 = 1,
        kShooter17mm2 = 2,
        kShooter42mm,
    } ShooterNumber;

    uint8_t Launching_Frequency;
    float initial_speed;
};

// ---- 0x0208
using RemainProjectileDataType = DataType<kRemainProjectile>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kRemainProjectile> {
    uint16_t ProjectileAllowance17mm;
    uint16_t ProjectileAllowance42mm;
    uint16_t RemainingGoldCoin;
};

// ---- 0x0209
using RFIDStatusDataType = DataType<kRFIDStatus>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kRFIDStatus> {
    uint32_t OurBase : 1; // bit 0

    uint32_t OurRingUpland : 1; // bit 1
    uint32_t TheirRingUpland : 1; // bit 2

    uint32_t OurTrapezoidalUpland3 : 1; // bit 3
    uint32_t TheirTrapezoidalUpland3 : 1; // bit 4

    uint32_t OurTrapezoidalUpland4 : 1; // bit 5
    uint32_t TheirTrapezoidalUpland4 : 1; // bit 6

    uint32_t OurEnergyMechanism : 1; // bit 7

    uint32_t OurFlyingSlopeNear : 1; // bit 8
    uint32_t OurFlyingSlopeFar : 1; // bit 9

    uint32_t TheirFlyingSlopeNear : 1; // bit 10
    uint32_t TheirFlyingSlopeFar : 1; // bit 11

    uint32_t OurOutpost : 1; // bit 12
    uint32_t OurHospital : 1; // bit 13

    uint32_t OurPatrolArea : 1; // bit 14
    uint32_t TheirPatrolArea : 1; // bit 15

    uint32_t OurResourceArea : 1; // bit 16
    uint32_t TheirResourceArea : 1; // bit 17

    uint32_t OurShop : 1; // bit 18

    uint32_t Center : 1; // bit 19

    uint32_t _ : 12;
};

// ---- 0x020A
using DartCmdDataType = DataType<kDartCmd>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kDartCmd> {
    enum : uint8_t {
        kOpen = 0,
        kClosed = 1,
        kToggling = 2,
    } Status;

    uint8_t _;
    uint16_t TargetChangingTimeSecond;
    uint16_t LatestLaunchCmdTimeSecond;
};

// ---- 0x020B
using GroundPosDataType = DataType<kGroundPos>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kGroundPos> {
    float_t HeroX;
    float_t HeroY;
    float_t EngineerX;
    float_t EngineerY;
    float_t Infantry3X;
    float_t Infantry3Y;
    float_t Infantry4X;
    float_t Infantry4Y;
    float_t Infantry5X;
    float_t Infantry5Y;
};

// ---- 0x020C
using RadarMarkDataType = DataType<kRadarMark>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kRadarMark> {
    uint8_t HeroProgress;
    uint8_t EngineerProgress;
    uint8_t Infantry3Progress;
    uint8_t Infantry4Progress;
    uint8_t Infantry5Progress;
    uint8_t SentryProgress;
};

// ---- 0x020D
using SentryDecDataType = DataType<kSentryDec>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kSentryDec> {
    uint32_t ProjectileAllowanceNum : 11;
    uint32_t ProjectileConversionCount : 4;
    uint32_t HPConversionCount : 4;
    uint32_t _ : 13;
};

// ---- 0x020E
using RadarDecDataType = DataType<kRadarDec>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kRadarDec> {
    uint8_t DoubleChance : 2;
    uint8_t DoubleGet : 1;
    uint8_t _ : 5;
};

// ---- 0x0301
template <typename DataType>
struct [[gnu::packed, gnu::aligned(1)]] InteractionDataType {
    enum : uint16_t {
        kDeleteLayer = 0x0100,
        kDraw1 = 0x0101,
        kDraw2 = 0x0102,
        kDraw5 = 0x0103,
        kDraw7 = 0x0104,
        kDrawString = 0x0110,
        kSentryCmd = 0x0120,
        kRadarCmd = 0x0121,
    } CmdID;

    uint16_t SenderId;
    uint16_t ReceiverId;
    DataType data;
};

// ---- 0x0301: 0x0100
struct [[gnu::packed, gnu::aligned(1)]] __DeleteLayerDataType {
    enum : uint8_t {
        kNone = 0,
        kDeleteLayer = 1,
        kDeleteAll = 2,
    } Type;

    uint8_t Layer;
};

using DeleteLayerDataType = InteractionDataType<__DeleteLayerDataType>;

// ---- 0x0301: 0x0101~0x0104
struct [[gnu::packed, gnu::aligned(1)]] DrawDataType {
    uint8_t Name[3];
    uint32_t OperateType : 3;
    uint32_t FigureType : 3;
    uint32_t Layer : 4;
    uint32_t Color : 4;
    uint32_t DetailsA : 9;
    uint32_t DetailsB : 9;
    uint32_t Width : 10;
    uint32_t StartX : 11;
    uint32_t StartY : 11;
    uint32_t DetailsC : 10;
    uint32_t DetailsD : 11;
    uint32_t DetailsE : 11;
};

// ---- 0x0301: 0x0101
using Draw1DataType = InteractionDataType<DrawDataType>;

// ---- 0x0301: 0x0102
using Draw2DataType = InteractionDataType<DrawDataType[2]>;

// ---- 0x0301: 0x0103
using Draw5DataType = InteractionDataType<DrawDataType[5]>;

// ---- 0x0301: 0x0104
using Draw7DataType = InteractionDataType<DrawDataType[7]>;

// ---- 0x0301: 0x0110
struct [[gnu::packed, gnu::aligned(1)]] __DrawStringDataType {
    DrawDataType Data;
    uint8_t String;
};

using DrawStringDataType = InteractionDataType<__DrawStringDataType>;

// ---- 0x0301: 0x0120
struct [[gnu::packed, gnu::aligned(1)]] SentryCmdDataType {
    uint32_t ConfirmedResurrection : 1;
    uint32_t ImmediateResurrection : 1;
    uint32_t ProjectileAllowanceNum : 11;
    uint32_t ProjectileConversionCount : 4;
    uint32_t HPConversionCount : 4;
    uint32_t _ : 11;
};

// ---- 0x0301: 0x0121
struct [[gnu::packed, gnu::aligned(1)]] RadarCmdDataType {
    uint8_t ConfirmDouble;
};

// ---- 0x0302
using CustomCtrlDataType = DataType<kCustomCtrl>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kCustomCtrl> {
    float X{};
    float Y{};
    float Z{};
    float Yaw{};
    float Pitch{};
    float Roll{};
    int16_t Reset;
    int16_t Memory;
    int16_t Loose;
};

// ---- 0x0303
using MapInteractionDataType = DataType<kMapInteraction>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kMapInteraction> {
    float TargetPositionX;
    float TargetPositionY;
    uint8_t CmdKeyboard;
    uint8_t TargetRobotId;
    uint8_t CmdSource;
};

// ---- 0x0304
using KeyMouseCtrlDataType = DataType<kKeyMouseCtrl>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kKeyMouseCtrl> {
    int16_t MouseX;
    int16_t MouseY;
    int16_t MouseZ;
    int8_t LeftButtonDown;
    int8_t RightButtonDown;

    struct [[gnu::packed, gnu::aligned(1)]] {
        uint16_t W : 1;
        uint16_t S : 1;
        uint16_t A : 1;
        uint16_t D : 1;
        uint16_t Shift : 1;
        uint16_t Ctrl : 1;
        uint16_t Q : 1;
        uint16_t E : 1;
        uint16_t R : 1;
        uint16_t F : 1;
        uint16_t G : 1;
        uint16_t Z : 1;
        uint16_t X : 1;
        uint16_t C : 1;
        uint16_t V : 1;
        uint16_t B : 1;
    } KeyBoard;

    uint16_t _;
};

// ---- 0x0305
using RadarDataType = DataType<kRadarData>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kRadarData> {
    uint16_t TargetID;
    float_t TargetX;
    float_t TargetY;
};

// ---- 0x0306
using CustomCtrlNoUsedDataType = DataType<kCustomCtrlNoUsed>;

template <>
struct [[deprecated("不接收也不发送该消息"), gnu::packed,
        gnu::aligned(1)]] DataType<kCustomCtrlNoUsed> {
};

// ---- 0x0307
using SentryDataType = DataType<kSentryData>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kSentryData> {
    enum : uint8_t {
        kAttackTarget = 1,
        kDefendTarget = 2,
        kMoveToTarget = 3,
    } Intention;

    uint16_t StartPositionXdm;
    uint16_t StartPositionYdm;
    int8_t DeltaX[49];
    int8_t DeltaY[49];
    uint16_t SenderID;
};

// ---- 0x0308
using MapDataType = DataType<kMapData>;

template <>
struct [[gnu::packed, gnu::aligned(1)]] DataType<kMapData> {
    uint16_t SenderID;
    uint16_t ReceiverID;
    uint8_t Data[30];
};
} // namespace ref_type

/* V1.6.2
 * 波特率 115200
 * 数据位 8
 * 停止位 1
 * 硬件流控 无
 * 校验位 无
 */
class DjiReferee {
public:
    ref_type::DataType<ref_type::kGameStatus> gameStatus_{};
    ref_type::DataType<ref_type::kGameResult> gameResult_{};
    ref_type::DataType<ref_type::kRobotHp> robotHp_{};
    ref_type::DataType<ref_type::kFieldEvent> fieldEvent_{};
    ref_type::DataType<ref_type::kSupply> supply_{};
    ref_type::DataType<ref_type::kWarning> warning_{};
    ref_type::DataType<ref_type::kDart> dart_{};
    ref_type::DataType<ref_type::kRobotPerf> robotPerf_{};
    ref_type::DataType<ref_type::kPowerAndHeat> powerAndHeat_{};
    ref_type::DataType<ref_type::kRobotPos> robotPos_{};
    ref_type::DataType<ref_type::kRobotGain> robotGain_{};
    ref_type::DataType<ref_type::kAirSupport> airSupport_{};
    ref_type::DataType<ref_type::kDamageStatus> damageStatus_{};
    ref_type::DataType<ref_type::kShootStatus> shootStatus_{};
    ref_type::DataType<ref_type::kRemainProjectile> remainProjectile_{};
    ref_type::DataType<ref_type::kRFIDStatus> rfidStatus_{};
    ref_type::DataType<ref_type::kDartCmd> dartCmd_{};
    ref_type::DataType<ref_type::kGroundPos> groundPos_{};
    ref_type::DataType<ref_type::kRadarMark> radarMark_{};
    ref_type::DataType<ref_type::kSentryDec> sentryDec_{};
    ref_type::DataType<ref_type::kRadarDec> radarDec_{};
    ref_type::DataType<ref_type::kMapInteraction> interaction_{};
    ref_type::DataType<ref_type::kCustomCtrl> customCtrl_{};
    ref_type::DataType<ref_type::kMapInteraction> mapInteraction_{};
    ref_type::DataType<ref_type::kKeyMouseCtrl> keyMouseCtrl_{};
    ref_type::DataType<ref_type::kRadarData> radarData_{};
    ref_type::DataType<ref_type::kSentryData> sentryData_{};
    ref_type::DataType<ref_type::kMapData> mapData_{};
    //        CustomCtrlNoUsedDataType _customCtrlNoUsed;

public:
    DjiReferee() = default;
    ~DjiReferee() = default;

    void Receive(std::uint8_t* rxBuffer, std::uint16_t len);
};
} // namespace dji

#if defined(BSP_HAS_USARTx)
namespace dji {
inline USART_TypeDef* operator>>(USART_TypeDef* uart, DjiReferee referee) {
    //  referee.Receive();
    return uart;
}
} // namespace dji
#endif